home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume17 / calentool / part15 < prev    next >
Encoding:
Internet Message Format  |  1991-04-06  |  54.5 KB

  1. From: billr@saab.CNA.TEK.COM (Bill Randle)
  2. Newsgroups: comp.sources.misc
  3. Subject: v17i096:  calentool - day/week/month/year-at-a-glance SunView tool, Part15/23
  4. Message-ID: <1991Apr6.024120.17402@sparky.IMD.Sterling.COM>
  5. Date: 6 Apr 91 02:41:20 GMT
  6. Approved: kent@sparky.imd.sterling.com
  7. X-Checksum-Snefru: 0d693485 9b58aab0 70bc166c 9f25fb0a
  8.  
  9. Submitted-by: Bill Randle <billr@saab.CNA.TEK.COM>
  10. Posting-number: Volume 17, Issue 96
  11. Archive-name: calentool/part15
  12.  
  13. #! /bin/sh
  14. # This is a shell archive.  Remove anything before this line, then unpack
  15. # it by saving it into a file and typing "sh file".  To overwrite existing
  16. # files, type "sh file -c".  You can also feed this as standard input via
  17. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  18. # will see the following message at the end:
  19. #        "End of archive 15 (of 23)."
  20. # Contents:  dates/gdead devent.c event.h mpaint.c
  21. # Wrapped by billr@saab on Thu Mar 28 08:38:26 1991
  22. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  23. if test -f 'dates/gdead' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'dates/gdead'\"
  25. else
  26. echo shar: Extracting \"'dates/gdead'\" \(9832 characters\)
  27. sed "s/^X//" >'dates/gdead' <<'END_OF_FILE'
  28. X# CalenTool V2.2 - nflag=1 range=1,12 - DO NOT REMOVE THIS LINE
  29. X# $Header: gdead,v 1.2 91/03/07 16:21:08 billr Exp $
  30. X#
  31. X# Dead Dates from the 1982 Dead Calendar
  32. X#     courtesy of Tom Uffner <tom@cis.udel.edu>
  33. X#
  34. X** 01 02 99 99 00 Psychedelic Shop opens, Haight St. SF (1966)
  35. X** 01 08 99 99 00 Acid Test Fillmore Aud. SF (1966)
  36. X** 01 09 99 99 00 Bill Graham born (1931)
  37. X** 01 13 99 99 00 "Stop Nuclear Power" benefit, Arlington Theatre, Santa Barbara (1978)
  38. X** 01 13 99 99 00 Cambodian Boat People's benefit, Oakland Col. w/ Joan Baez (1980)
  39. X** 01 14 99 99 00 Human Be-In, Golden Gate Park, SF, Dead, Airplane, Quicksilver (1967)
  40. X** 01 19 99 99 00 Janis Joplin born (1943)
  41. X** 01 21 99 99 00 Longshoreman's Hall Trips Festival, SF (thru 1-23-66)
  42. X** 01 22 99 99 00 Honolulu Civic Aud. (first show in Hawaii) (1970)
  43. X** 01 24 99 99 00 BAM's award, SF, Phil Lesh "best bassist" (1978)
  44. X** 01 30 99 99 00 BAM's award, SF, Mickey Hart "best drummer", Dead "best group" (1979)
  45. X** 01 31 99 99 00 Dead busted, New Orleans (1970)
  46. X** 02 04 99 99 00 Neal Cassady dies (1968)
  47. X** 02 08 99 99 00 Neal Cassady born (1926)
  48. X** 02 11 99 99 00 Watts Acid Test, Compton, CA (1966)
  49. X** 02 11 99 99 00 Fillmore East, NYC (w/ Duane and Gregg Allman, Peter Green) (1970)
  50. X** 02 13 99 99 00 'Bears Choice' recorded at Fillmore East, NYC (also 2-14-70) (1970)
  51. X** 02 13 99 99 00 "New Music for the 80's", Rhythm Devils debut, Marin, CA (1980)
  52. X** 02 14 99 99 00 Dead/Airplane open Carousel Ballroom, SF (1968)
  53. X** 02 17 99 99 00 "Rock for Life" benefit, Keith and Donna G.'s last show, Oakland (1979)
  54. X** 02 19 99 99 00 ESP Experiment show, Capital Theatre, Portchester, NY (1971)
  55. X** 02 23 99 99 00 Jefferson Airplane headline benefit for Dead's N.Orl. bust, Fill. W. (1970)
  56. X** 03 03 99 99 00 Haight Street, SF, free concert (1968)
  57. X** 03 05 99 99 00 Black Panther benefit, Oakland Aud. (1st show there), CA (1971)
  58. X** 03 05 99 99 00 Rolling Thunder benefit, Winterland, SF (1972)
  59. X** 03 08 99 99 00 Fillmore East opens, NYC (1968)
  60. X** 03 08 99 99 00 Pigpen found dead (1973)
  61. X** 03 12 99 99 00 Jack Kerouac born (1922)
  62. X** 03 15 99 99 00 Phil Lesh born (1940)
  63. X** 03 15 99 99 00 Benefit for SF Symphony ('Black and White Ball') Hilton Hotel, SF (1969)
  64. X** 03 20 99 99 00 Rainbow Theatre, London (also 3-21 thru 3-24) (1981)
  65. X** 03 23 99 99 00 Cow Palace debut of new sound system (25 tons, 641 spkrs, 48 amps) (1974)
  66. X** 03 23 99 99 00 S.N.A.C.K. benefit w/ Merl Saunders, Ned Lagin, Kezer Stad. SF (1975)
  67. X** 03 25 99 99 00 Academy of Music, NYC Donna's first show w/ Bo Diddley (1972)
  68. X** 03 25 99 99 00 BAM's award, SF, Jerry Garcia "Musician of the year" (1980)
  69. X** 03 28 99 99 00 Gruga Hall, Essen, Germany, w/ The Who, Flying Karamazov Bros. (1981)
  70. X** 04 01 99 99 00 "April Fools Show" Capital Theatre, Passaic, NJ (1980)
  71. X** 04 05 99 99 00 'Saturday Night Live' second appearance  (1980)
  72. X** 04 07 99 99 00 Europe '72 Tour begins, Empire Pool, Wembley, England (1972)
  73. X** 04 15 99 99 00 BAM's award, SF, Phil Lesh "best bassist" (1981)
  74. X** 04 20 99 99 00 People's Park planted, Berkeley (1969)
  75. X** 04 22 99 99 00 Brent Mydland's first show, Spartan Stadium, San Jose, CA (1979)
  76. X** 04 26 99 99 00 Fillmore East, NYC w/ Duane Allman (1971)
  77. X** 04 27 99 99 00 Fillmore East, NYC w/ Beach Boys (1971)
  78. X** 04 28 99 99 00 Fillmore Eest, NYC w/ Tom Constanten (1971)
  79. X** 04 29 99 99 00 Fillmore East, NYC last show (1971)
  80. X** 04 30 99 99 00 Casey Jones killed (1900)
  81. X** 05 06 99 99 00 MIT, Cambridge, MA free concert (1970)
  82. X** 05 07 99 99 00 Bill Kreutzmann born (1946)
  83. X** 05 07 99 99 00 'Tomorrow Show' interview and music (1981)
  84. X** 05 13 99 99 00 Lille Fairgrounds, France (free concert) (1972)
  85. X** 05 16 99 99 00 Diga Rhythm Band's first public appearance, Winterland w/ Starship  (1975)
  86. X** 05 24 99 99 00 Hollywood Festival Newcastle, England (first European show) (1970)
  87. X** 05 26 99 99 00 Europe '72 tour ends, Lyceum, London (1970)
  88. X** 05 26 99 99 00 Day on the Green #1, Kezer Stadim, SF w/ Dead, NRPS (1973)
  89. X** 05 27 99 99 00 First Avalon Ballroom show, SF (1966)
  90. X** 06 01 99 99 00 Haight Ashbury Free Clinic opens, SF (1967)
  91. X** 06 01 99 99 00 Dead Movie opens, Ziegfield Theatre, NYC (1977)
  92. X** 06 03 99 99 00 'The Vacation Ends', Dead begin touring again, Portland, OR  (1976)
  93. X** 06 06 99 99 00 'Seastones' debut at Dominican College, San Rafael, CA (1975)
  94. X** 06 07 99 99 00 15-year anniversary shows, Folsom Field, Univ. of CO, Boulder (1980)
  95. X** 06 08 99 99 00 Day on the Green w/ Beach Boys, Oakland (1974)
  96. X** 06 09 99 99 00 RFK Stadium, Wash. DC, w/ Allman Bros. (1973)
  97. X** 06 12 99 99 00 'Fire on the Mountain', Dead and Mt. St. Helens hit Portland (1980)
  98. X** 06 14 99 99 00 First Fillmore East show (1968)
  99. X** 06 15 99 99 00 Dead play at Straight Theatre christening party, SF (1967)
  100. X** 06 17 99 99 00 Pigpen's last show, Hollywood Bowl, CA (1972)
  101. X** 06 17 99 99 00 Bob Fried Memorial Boogie, Winterland, SF (1975)
  102. X** 06 18 99 99 00 Dead at Monterey Pop Festival (1967)
  103. X** 06 19 99 99 00 Summer Solstice shows, West High Aud., Anchorage, AK (thru 6-21) (1980)
  104. X** 06 21 99 99 00 Chateau de Herouville, France, free concert (1971)
  105. X** 06 22 99 99 00 Central Park, NYC free concert (1969)
  106. X** 06 23 99 99 00 Robert Hunter born (1941)
  107. X** 06 27 99 99 00 Fillmore East, NYC closes (1971)
  108. X** 06 29 99 99 00 Red Dog Saloon opens, Virginia City, NV (1965)
  109. X** 06 29 99 99 00 Canadian Train Tour begins, Toronto, ends 7-3 (1970)
  110. X** 07 02 99 99 00 Last Fillmore West show, SF (1971)
  111. X** 07 04 99 99 00 William Hitchcock's mansion, Millbrook, NY (1967)
  112. X** 07 04 99 99 00 Fillmore West closes, SF (1971)
  113. X** 07 08 99 99 00 Mississippi River Festival, Edwardsville, IL (1970)
  114. X** 07 12 99 99 00 Orpheum Theatre shows begin, ends 7-18 (1976)
  115. X** 07 19 99 99 00 Keith Godchaux born (1948)
  116. X** 07 23 99 99 00 Keith Godchaux dies (1980)
  117. X** 07 28 99 99 00 Watkins Glen, NY w/ Allman Bros., Band. 600,000 people (1973)
  118. X** 08 01 99 99 00 Jerry Garcia born (1942)
  119. X** 08 04 99 99 00 Newport Rock Festival, Costa Mesa, CA (1968)
  120. X** 08 07 99 99 00 Merry Pranksters "Welcome Hell's Angels' Party", La Honda, CA (1965)
  121. X** 08 13 99 99 00 Great American Music Hall, SF (1975)
  122. X** 08 15 99 99 00 Woodstock Music and Arts Festival, NY (Dead 8-16), thru 8-17 (1969)
  123. X** 08 20 99 99 00 First Fillmore West show, SF (1968)
  124. X** 08 22 99 99 00 Donna Jean Godchaux born (1947)
  125. X** 08 28 99 99 00 Springfield Creamery benefit, Lane County Fairgrounds, OR (1972)
  126. X** 08 31 99 99 00 Dead at New Orleans Pop Festival (1969)
  127. X** 09 03 99 99 00 Dead at Sky River Rock Festival, Washington (1968)
  128. X** 09 08 99 99 00 Ron "Pigpen" McKernan born (1945)
  129. X** 09 09 99 99 00 Alexandra Palace, London (start of '74 European Tour' (1974)
  130. X** 09 10 99 99 00 Rolling Thunder (1916)
  131. X** 09 11 99 99 00 Mickey Hart born (1943)
  132. X** 09 11 99 99 00 Ken Kesey born (1935)
  133. X** 09 14 99 99 00 Sound and Light Theatre, Gizah, Egypt, w/ Hamza El-Din, thru 9-16 (1978)
  134. X** 09 16 99 99 00 Albert Hoffman's first LSD experience (1943)
  135. X** 09 23 99 99 00 Jefferson Airplane/Muddy Waters headline first Winterland dance, SF (1966)
  136. X** 09 25 99 99 00 Warfield shows begin, SF (return of accoustic sets) (1980)
  137. X** 09 26 99 99 00 Record Factory auction of Dead artwork and memorabilia, San Rafael, SF (1976)
  138. X** 09 28 99 99 00 Last free Dead show in Golden Gate Park, SF w/ Starship (1975)
  139. X** 09 28 99 99 00 Cabrillo discovers California (1542 )
  140. X** 09 29 99 99 00 Mickey Hart's first show, Straight Theatre, SF (1967)
  141. X** 10 01 99 99 00 SF State College Acid Test (1966)
  142. X** 10 02 99 99 00 710 Ashbury Street bust (1967)
  143. X** 10 04 99 99 00 Janis Joplin dies (1970)
  144. X** 10 06 99 99 00 LSD declared illegal (1966)
  145. X** 10 06 99 99 00 'Death of Hippie' ceremony, SF (1967)
  146. X** 10 07 99 99 00 First Winterland show as "The Grateful Dead", SF (1966)
  147. X** 10 08 99 99 00 First 'Mickey and the Harbeats' show, The Matrix, SF (1968)
  148. X** 10 09 99 99 00 Roadie benefit, Winterland, SF (1972)
  149. X** 10 09 99 99 00 Who/Dead Day on the Green, Oakland, CA  (thru 10-10) (1976)
  150. X** 10 14 99 99 00 Warfield shows end, SF (1980)
  151. X** 10 15 99 99 00 Peace Festival, Mt. Tamalpais, CA (1966)
  152. X** 10 16 99 99 00 Bob Wier born (1947)
  153. X** 10 16 99 99 00 Dead 'retire' (five shows at Winterland), SF (1974)
  154. X** 10 19 99 99 00 Keith Godchaux's first show, Northrup Aud., Minn., MN (1971)
  155. X** 10 20 99 99 00 Mickey Hart rejoins band at Winterland (retirement shows end), SF (1974)
  156. X** 10 21 99 99 00 Brent Mydland born (1952)
  157. X** 10 21 99 99 00 Jack Kerouac dies (1969)
  158. X** 10 23 99 99 00 Radio City Music Hall shows begin, NYC (thru 10-31) (1980)
  159. X** 10 26 99 99 00 Dead play at North Face Ski Shop opening, SF (1966)
  160. X** 10 27 99 99 00 KSAN's live tape weekend (vintage Fillmore, Avalon tapes played), SF (1972)
  161. X** 11 06 99 99 00 Jefferson Airplane headline first Bill Graham show, SF (1965)
  162. X** 11 09 99 99 00 First issue of Rolling Stone published, SF (1967)
  163. X** 11 11 99 99 00 'Saturday Night Live' first appearance  (1978)
  164. X** 11 15 99 99 00 Moratorium Day, Lanai Theatre, Crockett, CA (1969)
  165. X** 11 15 99 99 00 Fillmore East, NYC w/ Winwood, Wood, Capaldi, Ramblin' Jack Elliot (1970)
  166. X** 11 17 99 99 00 Acoustic benefit for Hunger Week, Chicago's Loyola College (1978)
  167. X** 11 24 99 99 00 Capital Theatre, Passaic, NJ, nationwide broadcast (1978)
  168. X** 12 04 99 99 00 San Jose Acid Test (1965)
  169. X** 12 06 99 99 00 Mill Valley Recreation Center (free concert), CA (1980)
  170. X** 12 10 99 99 00 First Fillmore Auditorium show (2nd Mime Troupe benefit), SF (1965)
  171. X** 12 17 99 99 00 'Death and Rebirth of the Haight A. and Death of Money' parade, SF (1966)
  172. X** 12 18 99 99 00 Big Beat Club Acid Test, Palo Alto, CA (1965)
  173. X** 12 26 99 99 00 St. Stephens' Day
  174. X** 12 27 99 99 00 First Dead Head arrives for Winterland closing, SF  (1978)
  175. X** 12 31 99 99 00 First New Year's show Fillmore Auditorium, SR (1966)
  176. X** 12 31 99 99 00 New Year's Eve at The Ark, Boston, MA (1969)
  177. X** 12 31 99 99 00 Dead close Winterland, SF w/ Blues Bros., NRPS (1978)
  178. X
  179. END_OF_FILE
  180. if test 9832 -ne `wc -c <'dates/gdead'`; then
  181.     echo shar: \"'dates/gdead'\" unpacked with wrong size!
  182. fi
  183. # end of 'dates/gdead'
  184. fi
  185. if test -f 'devent.c' -a "${1}" != "-c" ; then 
  186.   echo shar: Will not clobber existing file \"'devent.c'\"
  187. else
  188. echo shar: Extracting \"'devent.c'\" \(30220 characters\)
  189. sed "s/^X//" >'devent.c' <<'END_OF_FILE'
  190. X/*
  191. X * $Header: devent.c,v 2.8 91/03/27 16:45:23 billr Exp $
  192. X */
  193. X/*
  194. X * devent.c
  195. X *
  196. X * Author: Philip Heller, Sun Microsystems. Inc. <terrapin!heller@sun.com>
  197. X *
  198. X * Original source Copyright (C) 1987, Sun Microsystems, Inc.
  199. X *    All Rights Reserved
  200. X * Permission is hereby granted to use and modify this program in source
  201. X * or binary form as long as it is not sold for profit and this copyright
  202. X * notice remains intact.
  203. X *
  204. X *
  205. X * Changes/additions by: Bill Randle, Tektronix, Inc. <billr@saab.CNA.TEK.COM>
  206. X *
  207. X * Changes and additions Copyright (C) 1988, 1989, 1991 Tektronix, Inc.
  208. X *    All Rights Reserved
  209. X * Permission is hereby granted to use and modify the modifications in source
  210. X * or binary form as long as they are not sold for profit and this copyright
  211. X * notice remains intact.
  212. X */
  213. X/********************************************************
  214. X *                            *
  215. X *      Day event routines for main subwindow.        *
  216. X *                            *
  217. X ********************************************************/
  218. X
  219. X
  220. X#include <stdio.h>
  221. X#include <suntool/sunview.h>
  222. X#include <suntool/canvas.h>
  223. X#include <suntool/panel.h>
  224. X#include <suntool/menu.h>
  225. X#include <suntool/seln.h>
  226. X#include <sys/time.h>
  227. X#include <fcntl.h>
  228. X#include "ct.h"
  229. X#include "event.h"
  230. X
  231. Xextern Menu day_sel_menu;
  232. Xextern Frame attr_frame;
  233. Xextern Panel_item everyx_pi, repeat_pi, remind_pi;
  234. Xextern Panel_item whichwk_pi, marked_pi, advw_pi;
  235. Xextern Panel_item del_choice_pi;
  236. Xextern Panel_item runl_pi;
  237. Xextern Frame del_frame;
  238. Xextern Panel del_panel;
  239. Xextern Pixrect tri_right_pr, tri_up_pr;
  240. Xextern Pixrect *leftarrow, *rightarrow, *morebutton;
  241. Xextern int n_tslots, n_slots, start_hour;
  242. Xextern Seln_client s_client;
  243. Xint attr_bi;
  244. Xstruct appt_entry shelf_appt = {0};
  245. Xint old_slot = -1;    /* for text cursor location */
  246. Xint box_index, found_flag;
  247. Xchar sel_text[MAX_STRLEN];
  248. Xstatic char *get_shelf();
  249. Xextern int chk_deleted();
  250. X
  251. Xday_inputevent(canvas, event)
  252. XCanvas canvas;
  253. XEvent *event;
  254. X{
  255. X    Menu_item an_item;
  256. X    int x, y;
  257. X    int i, j, active_above, strl;
  258. X    struct appt_entry *aptr;
  259. X    static int start_arrow_box = -1, prev_box = 0;
  260. X    static int expecting = 0;
  261. X    char *paste_str;
  262. X
  263. X        found_flag = 0;                    /* See if cursor is in a box. */
  264. X    /* translate coordinates back to pixwin space */
  265. X    event = canvas_window_event(canvas, event);
  266. X        x = event_x(event);
  267. X        y = event_y(event);
  268. X    if (event_id(event) == LOC_RGNEXIT && old_slot >= 0) {
  269. X        /* erase text cursor */
  270. X        text_cursor(old_slot);
  271. X        old_slot = -1;
  272. X    }
  273. X
  274. X        for (box_index=0; box_index<n_slots; box_index++) {
  275. X        /* is cursor inside a slot ? */
  276. X                if (x>=slots[box_index].slot_pos.left && x<=slots[box_index].slot_pos.right &&
  277. X                    y>=slots[box_index].slot_pos.top && y<=slots[box_index].slot_pos.bottom) {
  278. X                        found_flag = FOUND_SLOT;
  279. X                        break;
  280. X                }
  281. X        /* is cursor inside a "more" button ? */
  282. X                if (x>=slots[box_index].moreb_pos.left && x<=slots[box_index].moreb_pos.right &&
  283. X                    y>=slots[box_index].moreb_pos.top && y<=slots[box_index].moreb_pos.bottom) {
  284. X            if (slots[box_index].active > 1) {
  285. X                /* "more" button is active */
  286. X                found_flag = FOUND_MORE;
  287. X                break;
  288. X            }
  289. X        }
  290. X        /* is cursor inside a "leftarrow" button ? */
  291. X                if (x>=slots[box_index].larrow_pos.left && x<=slots[box_index].larrow_pos.right &&
  292. X                    y>=slots[box_index].larrow_pos.top && y<=slots[box_index].larrow_pos.bottom) {
  293. X            found_flag = FOUND_LARROW;
  294. X            break;
  295. X        }
  296. X        /* is cursor inside a "rightarrow" button ? */
  297. X                if (x>=slots[box_index].rarrow_pos.left && x<=slots[box_index].rarrow_pos.right &&
  298. X                    y>=slots[box_index].rarrow_pos.top && y<=slots[box_index].rarrow_pos.bottom) {
  299. X            found_flag = FOUND_RARROW;
  300. X            break;
  301. X        }
  302. X    }
  303. X    if (old_slot >= 0) {
  304. X        /* erase text cursor at old location */
  305. X        text_cursor(old_slot);
  306. X        old_slot = -1;
  307. X    }
  308. X
  309. X        if (!found_flag && !expecting)
  310. X                return(0);        /* Not in a box => ignore. */
  311. X
  312. X    if (event_id(event) == LOC_STILL || (event_is_button(event) && event_is_up(event))) {
  313. X        if (found_flag == FOUND_SLOT && box_index != old_slot)
  314. X            /* in a different slot than we were before */
  315. X            if (slots[box_index].active)
  316. X                /* display cursor at new location */
  317. X              text_cursor(box_index);
  318. X          }
  319. X        if (found_flag == FOUND_SLOT && event_id(event) == KEY_LEFT(8)
  320. X        && event_is_up(event)) {
  321. X        /*
  322. X         * Process a "Paste" ("Get") event by pasting the text
  323. X         * from the SHELF. Note that this is different from
  324. X         * pasting an appointment.
  325. X         */
  326. X        if (!slots[box_index].active)
  327. X            return(0);
  328. X        new_entry = 1;    /* flag for file updating */
  329. X        strl = strlen(slots[box_index].cur_appt->str);
  330. X        paste_str = get_shelf();
  331. X        if (paste_str == NULL) {
  332. X            text_cursor(box_index);
  333. X            return(0);
  334. X        }
  335. X        strncpy(slots[box_index].cur_appt->str + strl, paste_str,
  336. X            min(strlen(paste_str),MAX_STRLEN - strl ));
  337. X        slots[box_index].cur_appt->str[min(strlen(paste_str) + strl, MAX_STRLEN)] = '\0';
  338. X        rewrite_string(box_index, JUSTIFY_LEFT);
  339. X        /* display cursor at new location */
  340. X        text_cursor(box_index);
  341. X    } else if (event_id(event) == KEY_LEFT(6) && event_is_up(event)) {
  342. X        /* put string for current appt on the shelf */
  343. X        if (found_flag == FOUND_SLOT && slots[box_index].active)
  344. X            /* we're in an active slot */
  345. X            strcpy(sel_text, slots[box_index].cur_appt->str);
  346. X        else
  347. X            sel_text[0] = '\0';
  348. X    } else if (found_flag == FOUND_SLOT && event_id(event) <= ASCII_LAST) {
  349. X        /* Process a kbd event. */
  350. X                if (!slots[box_index].active)
  351. X                        return(0);
  352. X        if (event_id(event) == CTRL_R) {
  353. X                        rewrite_string(box_index, JUSTIFY_LEFT);
  354. X                        return(0);
  355. X        }
  356. X        if (slots[box_index].cur_appt->flags & READONLY)
  357. X            return(0);
  358. X        new_entry = 1;    /* flag for file updating */
  359. X        strl = strlen(slots[box_index].cur_appt->str);
  360. X                if (event_id(event) == CTRL_U) {
  361. X                        slots[box_index].cur_appt->str[0] = '\0';
  362. X                        rewrite_string(box_index, JUSTIFY_LEFT);
  363. X                } else if (event_id(event) == CTRL_W) {
  364. X                        while (strl > 0 && slots[box_index].cur_appt->str[strl-1] != ' ') {
  365. X                                slots[box_index].cur_appt->str[strl-1] = '\0';
  366. X                strl--;
  367. X                        }
  368. X            rewrite_string(box_index, JUSTIFY_RIGHT);
  369. X                } else if (event_id(event) == DEL || event_id(event) == BACKSPACE) {
  370. X            if (strl > 0) {
  371. X                                slots[box_index].cur_appt->str[strl-1] = '\0';
  372. X                                rewrite_string(box_index, JUSTIFY_RIGHT);
  373. X                        }
  374. X                } else if (event_id(event) >= (int)' ' && strl < MAX_STRLEN-2) {
  375. X                        slots[box_index].cur_appt->str[strl] = (char)event_id(event);
  376. X            slots[box_index].cur_appt->str[strl+1] = '\0';
  377. X                        rewrite_string(box_index, JUSTIFY_RIGHT);
  378. X                }
  379. X        /* display cursor at new location */
  380. X        text_cursor(box_index);
  381. X    } else if (event_id(event) == MS_LEFT && event_is_down(event)) {
  382. X        /* LB down event */
  383. X        switch (found_flag) {
  384. X            case FOUND_SLOT:
  385. X                break;
  386. X            case FOUND_MORE:
  387. X                /* reverse video "more" button */
  388. X                pw_rop(main_pixwin, slots[box_index].moreb_pos.left, slots[box_index].moreb_pos.top,
  389. X                    morebutton->pr_width, morebutton->pr_height, PIX_NOT(PIX_DST),
  390. X                    morebutton, 0, 0);
  391. X                expecting = box_index + (FOUND_MORE<<8);
  392. X                break;
  393. X            case FOUND_LARROW:
  394. X                do_left_arrow(canvas, box_index);
  395. X                break;
  396. X            case FOUND_RARROW:
  397. X                do_right_arrow(canvas, box_index);
  398. X                break;
  399. X        }
  400. X    } else if (event_id(event) == MS_LEFT && event_is_up(event)) {
  401. X        /* Process an LB up click. */
  402. X        i = expecting>>8;
  403. X        if (expecting && found_flag != i) {
  404. X            /* return button to normal video */
  405. X            if (i == FOUND_MORE) {
  406. X                /* "more" button */
  407. X                i = expecting & 0xff;
  408. X                pw_rop(main_pixwin, slots[i].moreb_pos.left, slots[i].moreb_pos.top,
  409. X                    morebutton->pr_width, morebutton->pr_height, PIX_SRC,
  410. X                    morebutton, 0, 0);
  411. X            }
  412. X        } else {
  413. X            switch (found_flag) {
  414. X                case FOUND_SLOT:
  415. X                    if (!read_only) {
  416. X                        make_box_active(box_index);
  417. X                        new_entry = 1;
  418. X                    }
  419. X                    break;
  420. X                case FOUND_MORE:
  421. X                    next_appt(box_index, TRUE);
  422. X                    /* normal video "more" button */
  423. X                    pw_rop(main_pixwin, slots[box_index].moreb_pos.left, slots[box_index].moreb_pos.top,
  424. X                        morebutton->pr_width, morebutton->pr_height, PIX_SRC,
  425. X                        morebutton, 0, 0);
  426. X                    break;
  427. X                case FOUND_LARROW:
  428. X                    break;
  429. X                case FOUND_RARROW:
  430. X                    break;
  431. X            }
  432. X        }
  433. X        expecting = 0;
  434. X    } else if (found_flag == FOUND_SLOT && event_id(event) == MS_MIDDLE) {
  435. X        /* Process a MB click. */
  436. X        if (event_is_down(event)) {
  437. X            /* try to start dragging from here */
  438. X            if (!slots[box_index].active || box_index >= n_tslots) {
  439. X                /* not allowed in notes slots, either */
  440. X                start_arrow_box = -1;
  441. X                return(0);
  442. X            }
  443. X            if ((slots[box_index].cur_appt->flags & READONLY) || read_only) {
  444. X                start_arrow_box = -1;
  445. X                return(0);
  446. X            }
  447. X            if (slots[box_index].cur_appt->arrows > 0) {
  448. X                /* remove old arrows and adjust counts */
  449. X                deactivate_lower_arrows(box_index, TRUE);
  450. X                j = slots[box_index].cur_appt->arrows;
  451. X                while (j > 0)
  452. X                    slots[box_index+(j--)].count--;
  453. X                slots[box_index].cur_appt->arrows = 0;
  454. X            }
  455. X            prev_box = start_arrow_box = box_index;
  456. X        } else {
  457. X            if (box_index >= n_tslots) {
  458. X                /* mouse currently in notes section */
  459. X                if (start_arrow_box == -1)
  460. X                    /* started in notes section, too */
  461. X                    return(0);
  462. X                else
  463. X                    /* truncate at start of notes section */
  464. X                    box_index = n_tslots - 1;
  465. X            }
  466. X            /* end of dragging => end of arrow */
  467. X            if (box_index > start_arrow_box && start_arrow_box != -1) {
  468. X                int left = (dayslot_width-2)/2 - 8;
  469. X
  470. X                i = start_arrow_box;
  471. X                slots[i].cur_appt->arrows = box_index - start_arrow_box;
  472. X                while (++i < box_index) {
  473. X                    slots[i].count++;
  474. X                    /*
  475. X                     * erase arrow shaft on boxes - it will be
  476. X                     * replaced by a real arrowshaft during redraw
  477. X                     */
  478. X                    pw_rop(main_pixwin, slots[i].slot_pos.left+left,
  479. X                        slots[i].slot_pos.top+1,
  480. X                        16, dayslot_height-2,
  481. X                        PIX_SRC^PIX_DST, arrowshaft_pr,
  482. X                        0, 0);
  483. X                }
  484. X                slots[i].count++;
  485. X                /*
  486. X                 * erase arrow shaft on last box - it will be
  487. X                 * replaced by an arrowhead during redraw
  488. X                 */
  489. X                pw_rop(main_pixwin, slots[i].slot_pos.left+left,
  490. X                    slots[i].slot_pos.top+1,
  491. X                    16, dayslot_height-2,
  492. X                    PIX_SRC^PIX_DST, arrowshaft_pr,
  493. X                    0, 0);
  494. X            }
  495. X            start_arrow_box = -1;
  496. X            new_entry = 1;
  497. X            draw_day_appts();
  498. X        }
  499. X    } else if (found_flag == FOUND_SLOT && event_id(event) == LOC_DRAG) {
  500. X        /* mouse dragging - is it the middle button ? */
  501. X        if ((int)window_get(canvas, WIN_EVENT_STATE, MS_MIDDLE) && start_arrow_box >= 0) {
  502. X            int left = (dayslot_width-2)/2 - 8;
  503. X
  504. X            if (box_index >= n_tslots)
  505. X                /* don't flow into notes section */
  506. X                box_index = n_tslots - 1;
  507. X            /*
  508. X             * xor arrow shaft thru current slot so
  509. X             * we can see where we're dragging
  510. X             */
  511. X            if (box_index > prev_box) {
  512. X                while (++prev_box <= box_index) {
  513. X                    pw_rop(main_pixwin, slots[prev_box].slot_pos.left+left,
  514. X                        slots[prev_box].slot_pos.top+1,
  515. X                        16, dayslot_height-2,
  516. X                        PIX_SRC^PIX_DST, arrowshaft_pr,
  517. X                        0, 0);
  518. X                }
  519. X                prev_box = box_index;
  520. X            } else if (box_index < prev_box && box_index >= start_arrow_box) {
  521. X                /* going backwards - cleanup as we go */
  522. X                while (prev_box > box_index) {
  523. X                    pw_rop(main_pixwin, slots[prev_box].slot_pos.left+left,
  524. X                        slots[prev_box].slot_pos.top+1,
  525. X                        16, dayslot_height-2,
  526. X                        PIX_SRC^PIX_DST, arrowshaft_pr,
  527. X                        0, 0);
  528. X                    --prev_box;
  529. X                }
  530. X            }
  531. X        }
  532. X    } else if (found_flag == FOUND_SLOT && event_id(event) == MS_RIGHT && event_is_down(event)) {
  533. X        /* Process a RB click. */
  534. X        /*
  535. X         * display popup menu of choices, but first disable
  536. X         * certain entries if this is a readonly appointment
  537. X         * or an empty slot.
  538. X         */
  539. X        /* undelete - almost always inactive */
  540. X        an_item = menu_get(day_sel_menu, MENU_NTH_ITEM, MUNDELETE);
  541. X        menu_set(an_item, MENU_INACTIVE, TRUE, 0);
  542. X        if (!slots[box_index].first) {
  543. X            /* empty slot. only paste active */
  544. X            paste_only();
  545. X        } else if (slots[box_index].cur_appt->flags & READONLY) {
  546. X            /* readonly => paste and copy only */
  547. X            paste_only();
  548. X            /* copy */
  549. X            an_item = menu_get(day_sel_menu, MENU_NTH_ITEM, MCOPY);
  550. X            menu_set(an_item, MENU_INACTIVE, FALSE, 0);
  551. X        } else {
  552. X            /* delete */
  553. X            an_item = menu_get(day_sel_menu, MENU_NTH_ITEM, MDELETE);
  554. X            menu_set(an_item, MENU_INACTIVE, FALSE, 0);
  555. X            /* cut */
  556. X            an_item = menu_get(day_sel_menu, MENU_NTH_ITEM, MCUT);
  557. X            menu_set(an_item, MENU_INACTIVE, FALSE, 0);
  558. X            /* copy */
  559. X            an_item = menu_get(day_sel_menu, MENU_NTH_ITEM, MCOPY);
  560. X            menu_set(an_item, MENU_INACTIVE, FALSE, 0);
  561. X            /* modify */
  562. X            an_item = menu_get(day_sel_menu, MENU_NTH_ITEM, MMODIFY);
  563. X            menu_set(an_item, MENU_INACTIVE, FALSE, 0);
  564. X            for (aptr=slots[box_index].first; aptr; aptr=aptr->next)
  565. X                if (aptr->flags & DELETED) {
  566. X                    if (!slots[box_index].active)
  567. X                        /* only paste and undelete */
  568. X                        paste_only();
  569. X                    /* undelete */
  570. X                    an_item = menu_get(day_sel_menu, MENU_NTH_ITEM, MUNDELETE);
  571. X                    menu_set(an_item, MENU_INACTIVE, FALSE, 0);
  572. X                    break;
  573. X                }
  574. X        }
  575. X        i = (int) menu_show(day_sel_menu, canvas, event, 0);
  576. X        if (i > 0) {
  577. X            switch (i) {
  578. X                case MDELETE:
  579. X                    delete_appt(box_index, canvas);
  580. X                    break;
  581. X                case MCUT:
  582. X                    cut_appt(box_index, canvas);
  583. X                    break;
  584. X                case MCOPY:
  585. X                    copy_appt(box_index);
  586. X                    break;
  587. X                case MPASTE:
  588. X                    paste_appt(box_index);
  589. X                    break;
  590. X                case MMODIFY:
  591. X                    modify_appt(box_index, canvas);
  592. X                    break;
  593. X                case MUNDELETE:
  594. X                    undelete_appt(box_index);
  595. X                    break;
  596. X            }
  597. X            if (new_entry) {
  598. X                close_day();
  599. X                draw_day();    /* redraw display */
  600. X            }
  601. X        }
  602. X    } else
  603. X        window_default_event_proc(canvas, event, 0);
  604. X    return(1);
  605. X}
  606. X
  607. X
  608. X/* make "paste" the only active menu entry */
  609. Xpaste_only()
  610. X{
  611. X    Menu_item an_item;
  612. X
  613. X    /* delete */
  614. X    an_item = menu_get(day_sel_menu, MENU_NTH_ITEM, MDELETE);
  615. X    menu_set(an_item, MENU_INACTIVE, TRUE, 0);
  616. X    /* cut */
  617. X    an_item = menu_get(day_sel_menu, MENU_NTH_ITEM, MCUT);
  618. X    menu_set(an_item, MENU_INACTIVE, TRUE, 0);
  619. X    /* copy */
  620. X    an_item = menu_get(day_sel_menu, MENU_NTH_ITEM, MCOPY);
  621. X    menu_set(an_item, MENU_INACTIVE, TRUE, 0);
  622. X    /* modify */
  623. X    an_item = menu_get(day_sel_menu, MENU_NTH_ITEM, MMODIFY);
  624. X    menu_set(an_item, MENU_INACTIVE, TRUE, 0);
  625. X}
  626. X
  627. X/* draw (or erase) text cursor in a day slot */
  628. Xtext_cursor(slotno)
  629. Xint slotno;
  630. X{
  631. X    int    strl, x;
  632. X
  633. X    strl = strlen(&slots[slotno].cur_appt->str[slots[slotno].cur_appt->sindex]);
  634. X    if (strl <= (day_message_size-1)) {
  635. X        x = slots[slotno].slot_pos.left + strl * font->pf_defaultsize.x;
  636. X        pw_write(main_pixwin, x, slots[slotno].slot_pos.bottom-4,
  637. X          16, 16, PIX_SRC^PIX_DST, &tri_up_pr, 0, 0);
  638. X    }
  639. X    old_slot = slotno;
  640. X}
  641. X
  642. X/* make slot active */
  643. Xmake_box_active(bi)
  644. Xint bi;
  645. X{
  646. X    add_to_slot(bi, NULL, TRUE);
  647. X    fill_appt(bi);
  648. X    rewrite_string(bi, JUSTIFY_LEFT);
  649. X    text_cursor(bi);
  650. X}
  651. X
  652. X/* activate a hidden appt and make it visible */
  653. Xint
  654. Xactivate_slot(bi, dpyflag)
  655. Xint bi;
  656. Xint dpyflag;
  657. X{
  658. X    if (slots[bi].active <= 0)
  659. X        /* nothing to activate */
  660. X        return(0);
  661. X
  662. X    if (dpyflag)
  663. X        draw_day_appts();    /* redraw display */
  664. X
  665. X    return(1);
  666. X}
  667. X
  668. X/* clears a day slot */
  669. Xdeactivate_slot(bi, dpyflag)
  670. Xint bi, dpyflag;
  671. X{
  672. X    if (!dpyflag)
  673. X        return;
  674. X    /* erase text cursor at old location */
  675. X    if (old_slot >= 0) {
  676. X        text_cursor(old_slot);
  677. X        old_slot = -1;
  678. X    }
  679. X    /* erase displayed slot */
  680. X    if (!ymd_compare(current, today))
  681. X        pw_write(main_pixwin, slots[bi].slot_pos.left, slots[bi].slot_pos.top,
  682. X          dayslot_width, dayslot_height, PIX_SRC, timeslot_td_pr, 0, 0);
  683. X    else
  684. X        pw_write(main_pixwin, slots[bi].slot_pos.left+1, slots[bi].slot_pos.top+1,
  685. X          dayslot_width-2, dayslot_height-2, PIX_CLR, NULL, 0, 0);
  686. X    if (slots[bi].cur_appt->arrows > 0)
  687. X        deactivate_lower_arrows(bi, dpyflag);
  688. X}
  689. X
  690. X/* clear any displayed arrowshafts and arrowheads */
  691. Xdeactivate_lower_arrows(bi, dpyflag)
  692. Xint bi, dpyflag;
  693. X{
  694. X    int narrows, offset;
  695. X
  696. X    if (!dpyflag)
  697. X        return;
  698. X    narrows = slots[bi].cur_appt->arrows;
  699. X    offset = (slots[bi].count - slots[bi].active + 1) * 40;
  700. X    while (narrows-- > 0) {
  701. X        bi++;
  702. X        if (slots[bi].active)
  703. X            continue;
  704. X        /* erase displayed arrowshaft or arrowhead */
  705. X        if (!ymd_compare(current, today))
  706. X            pw_write(main_pixwin, slots[bi].slot_pos.left+1+offset,
  707. X              slots[bi].slot_pos.top+1, 16,
  708. X              dayslot_height-2, PIX_SRC, timeslot_td_pr, 0, 0);
  709. X        else
  710. X            pw_write(main_pixwin, slots[bi].slot_pos.left+1+offset,
  711. X              slots[bi].slot_pos.top+1, 16,
  712. X              dayslot_height-2, PIX_CLR, NULL, 0, 0);
  713. X    }
  714. X}
  715. X
  716. X/* fill in appt struct with current info */
  717. Xfill_appt(bi)
  718. Xint bi;
  719. X{
  720. X    int s_hour, s_minute, n_arrows;
  721. X
  722. X    slots[bi].cur_appt->year = current.tm_year;
  723. X    slots[bi].cur_appt->month = current.tm_mon;
  724. X    slots[bi].cur_appt->day = current.tm_mday;
  725. X    slots[bi].cur_appt->arrows = 0;
  726. X    slots[bi].cur_appt->flags = slots[bi].cur_appt->repeat = 0;
  727. X    slots[bi].cur_appt->lookahead = slots[bi].cur_appt->sindex = 0;
  728. X    slots[bi].cur_appt->runlength = 0;
  729. X    slots[bi].cur_appt->warn = 10;
  730. X    if (bi >= n_tslots) {
  731. X        /* notes section */
  732. X        slots[bi].cur_appt->hour = 99;
  733. X        slots[bi].cur_appt->minute = 0;
  734. X        slots[bi].cur_appt->flags = A_NOTE;
  735. X    } else {
  736. X        /* regular appt */
  737. X        slots[bi].cur_appt->hour = bi/2 + start_hour;
  738. X        slots[bi].cur_appt->minute = (bi % 2) * 30;
  739. X    }
  740. X    slots[bi].cur_appt->str[0] = '\0';
  741. X}
  742. X
  743. X/*
  744. X * Display delete popup window to let user choose delete mode for
  745. X * recurring appts (delete this one only or delete all), otherwise,
  746. X * just wipe it out with no options.
  747. X */
  748. Xdelete_appt(bi, canvas)
  749. Xint bi;
  750. XCanvas canvas;
  751. X{
  752. X    Rect *canvas_r;
  753. X    int top, left, width, height;
  754. X
  755. X    if (slots[bi].cur_appt->flags & READONLY) {
  756. X        err_rpt("Can't delete a read-only appt", NON_FATAL);
  757. X        return;
  758. X    }
  759. X    if (Repeating(slots[bi].cur_appt->flags)) {
  760. X        attr_bi = bi;    /* set global index for notify func */
  761. X
  762. X        /* get x,y position of canvas window on the screen so we
  763. X         * can center popup window in it.
  764. X         */
  765. X        canvas_r = (Rect *) window_get(canvas, WIN_RECT);
  766. X        panel_set(del_choice_pi, PANEL_CHOICE_STRINGS,
  767. X            "Delete this occurrance only",
  768. X            "Delete all occurrances", 0,
  769. X            PANEL_CLIENT_DATA, 0,
  770. X            0);
  771. X        window_fit(del_panel);
  772. X        window_fit(del_frame);
  773. X        width = (int) window_get(del_frame, WIN_WIDTH);
  774. X        height = (int) window_get(del_frame, WIN_HEIGHT);
  775. X        left =  canvas_r->r_left + (canvas_r->r_width - width) / 2;
  776. X        top =  canvas_r->r_top + (canvas_r->r_height - height) / 2;
  777. X        window_set(del_frame, WIN_X, left, WIN_Y, top, 0);
  778. X        panel_set_value(del_choice_pi, 0);
  779. X
  780. X        window_loop(del_frame);    /* let user select things */
  781. X    } else {
  782. X        cut_delete(bi);
  783. X        new_entry = 1;
  784. X    }
  785. X}
  786. X
  787. Xcut_appt(bi, canvas)
  788. Xint bi;
  789. XCanvas canvas;
  790. X{
  791. X    Rect *canvas_r;
  792. X    int top, left, width, height;
  793. X    int i;
  794. X
  795. X    /* cut (delete) current entry, saving the info on the "shelf" */
  796. X    if (slots[bi].cur_appt->flags & READONLY) {
  797. X        err_rpt("Can't cut a read-only appt", NON_FATAL);
  798. X        return;
  799. X    }
  800. X    shelf_appt = *slots[bi].cur_appt;
  801. X    if (Repeating(slots[bi].cur_appt->flags)) {
  802. X        attr_bi = bi;    /* set global index for notify func */
  803. X
  804. X        /* get x,y position of canvas window on the screen so we
  805. X         * can center popup window in it.
  806. X         */
  807. X        canvas_r = (Rect *) window_get(canvas, WIN_RECT);
  808. X        panel_set(del_choice_pi, PANEL_CHOICE_STRINGS,
  809. X            "Move this occurrance only",
  810. X            "Move all occurrances", 0,
  811. X            PANEL_CLIENT_DATA, 1,
  812. X            0);
  813. X        window_fit(del_panel);
  814. X        window_fit(del_frame);
  815. X        width = (int) window_get(del_frame, WIN_WIDTH);
  816. X        height = (int) window_get(del_frame, WIN_HEIGHT);
  817. X        left =  canvas_r->r_left + (canvas_r->r_width - width) / 2;
  818. X        top =  canvas_r->r_top + (canvas_r->r_height - height) / 2;
  819. X        window_set(del_frame, WIN_X, left, WIN_Y, top, 0);
  820. X        panel_set_value(del_choice_pi, 0);
  821. X
  822. X        window_loop(del_frame);    /* let user select things */
  823. X    } else {
  824. X        cut_delete(bi);
  825. X        new_entry = 1;
  826. X    }
  827. X}
  828. X
  829. Xcut_delete(bi)
  830. Xint bi;
  831. X{
  832. X    int j;
  833. X    struct appt_entry *aptr, *cptr, *optr;
  834. X
  835. X    cptr = slots[bi].cur_appt;
  836. X    slots[bi].count--;
  837. X    slots[bi].active--;
  838. X    deactivate_slot(bi, TRUE);
  839. X    if ( (j = cptr->arrows) > 0) {
  840. X        /* adjust counts */
  841. X        while (j > 0)
  842. X            slots[bi+(j--)].count--;
  843. X    }
  844. X    if (slots[bi].cur_appt == slots[bi].first) {
  845. X        /* displaying first entry in list */
  846. X        /* see if there's any more */
  847. X        if (slots[bi].first->next)
  848. X            slots[bi].first = slots[bi].first->next;
  849. X        else {
  850. X            /* last one */
  851. X            slots[bi].first = NULL;
  852. X            slots[bi].active = 0;
  853. X        }
  854. X        slots[bi].cur_appt = slots[bi].first;
  855. X    } else {
  856. X        /* not first, so find previous one to this */
  857. X        for (aptr=slots[bi].first; slots[bi].cur_appt!=aptr; optr=aptr,aptr=aptr->next)
  858. X            ;
  859. X        slots[bi].cur_appt = optr->next = aptr->next;
  860. X        if (!optr->next)
  861. X            slots[bi].cur_appt = slots[bi].first;
  862. X    }
  863. X    free(cptr);
  864. X    (void)activate_slot(bi, TRUE);    /* show any hidden appts */
  865. X}
  866. X
  867. Xcopy_appt(bi)
  868. Xint bi;
  869. X{
  870. X    /* copy current entry, saving the info on the "shelf" */
  871. X    shelf_appt = *slots[bi].cur_appt;
  872. X}
  873. X
  874. Xpaste_appt(bi)
  875. Xint bi;
  876. X{
  877. X    int j;
  878. X
  879. X    /* insert the saved entry (if any) */
  880. X    if (shelf_appt.str[0] == '\0') {
  881. X        err_rpt("nothing to paste", NON_FATAL);
  882. X        return;
  883. X    }
  884. X    shelf_appt.year = current.tm_year;
  885. X    shelf_appt.month = current.tm_mon;
  886. X    shelf_appt.day = current.tm_mday;
  887. X    if (shelf_appt.flags & EVERY_SOMEDAY) {
  888. X        /* change repeating appt to this day */
  889. X        shelf_appt.flags &= ~EVERY_SOMEDAY;
  890. X        shelf_appt.flags |= Setday(current.tm_wday);
  891. X    }
  892. X    if (bi >= n_tslots) {
  893. X        /* notes section */
  894. X        shelf_appt.hour = 99;
  895. X        shelf_appt.minute = 0;
  896. X        /* just in case converting from time to note */
  897. X        shelf_appt.flags |= A_NOTE;
  898. X    } else {
  899. X        /* regular appt */
  900. X        shelf_appt.hour = bi/2 + start_hour;
  901. X        shelf_appt.minute = (bi % 2) * 30;
  902. X        /* just in case converting from note to time */
  903. X        shelf_appt.flags &= ~MARKED_NOTE;
  904. X    }
  905. X    add_to_slot(bi, &shelf_appt, TRUE);
  906. X    new_entry = 1;
  907. X}
  908. X
  909. X/*
  910. X * Display attributes popup window to let user modify
  911. X * various appointment options (such as repeat interval,
  912. X * etc.)
  913. X */
  914. Xmodify_appt(bi, canvas)
  915. Xint bi;
  916. XCanvas canvas;
  917. X{
  918. X    Rect *canvas_r;
  919. X    int top, left, width, height;
  920. X
  921. X    if (slots[bi].cur_appt->flags & READONLY) {
  922. X        err_rpt("Can't modify a read-only appt", NON_FATAL);
  923. X        return;
  924. X    }
  925. X    attr_bi = bi;    /* set global index for notify func */
  926. X    set_attr();    /* set panel item current values */
  927. X
  928. X    /* get x,y position of canvas window on the screen so we
  929. X     * can center this one in it.
  930. X     */
  931. X    canvas_r = (Rect *) window_get(canvas, WIN_RECT);
  932. X    width = (int) window_get(attr_frame, WIN_WIDTH);
  933. X    height = (int) window_get(attr_frame, WIN_HEIGHT);
  934. X    left =  canvas_r->r_left + (canvas_r->r_width - width) / 2;
  935. X    top =  canvas_r->r_top + (canvas_r->r_height - height) / 2;
  936. X    window_set(attr_frame, WIN_X, left, WIN_Y, top, 0);
  937. X
  938. X    window_loop(attr_frame);    /* let user select things */
  939. X    window_set(attr_frame, WIN_SHOW, FALSE, 0);
  940. X}
  941. X
  942. X/* undelete a recurring appointment for this day */
  943. X/* we only get here if a deleted appt exists */
  944. Xundelete_appt(bi)
  945. Xint bi;
  946. X{
  947. X    struct appt_entry *aptr, *optr;
  948. X
  949. X    /* search list to find deleted entry */
  950. X    for (optr=aptr=slots[bi].first; aptr; optr=aptr,aptr=aptr->next)
  951. X        if (aptr->flags & DELETED)
  952. X            break;
  953. X    if (aptr == slots[bi].first)
  954. X        slots[bi].first = aptr->next;
  955. X    else
  956. X        optr->next = aptr->next;
  957. X    slots[bi].count++;
  958. X    slots[bi].active++;
  959. X    if (slots[bi].active == 1) {
  960. X        slots[bi].cur_appt = slots[bi].first;
  961. X        (void)activate_slot(bi, TRUE);
  962. X    }
  963. X    free(aptr);
  964. X    new_entry = 1;
  965. X}
  966. X
  967. Xset_attr()
  968. X{
  969. X    int everyx_val = 0, whichwk_val = 0;
  970. X    char str[5];
  971. X    struct appt_entry *apt = slots[attr_bi].cur_appt;
  972. X
  973. X    panel_set_value(repeat_pi, "");    /* set default */
  974. X    panel_set_value(remind_pi, "");    /* set default */
  975. X    panel_set_value(runl_pi, "");    /* set default */
  976. X    if (apt->flags & EVERY_MON_FRI)
  977. X        everyx_val |= 0x1;
  978. X    else if (apt->flags & ALL_DAYS)
  979. X        everyx_val |= 0x2;
  980. X    if (apt->flags & ALL_MONTHS)
  981. X        everyx_val |= 0x8;
  982. X    if (apt->flags & ALL_YEARS)
  983. X        everyx_val |= 0x10;
  984. X    if (apt->flags & EVERY_SOMEDAY) {
  985. X        everyx_val |= 0x4;
  986. X        if (apt->repeat == ALL_WEEKS)
  987. X            whichwk_val = 0x40;
  988. X        else
  989. X            whichwk_val = apt->repeat;
  990. X        panel_set(repeat_pi, PANEL_SHOW_ITEM, FALSE, 0);
  991. X        panel_set(whichwk_pi, PANEL_SHOW_ITEM, TRUE, 0);
  992. X    } else {
  993. X        if (apt->repeat) {
  994. X            sprintf(str, "%d", apt->repeat);
  995. X            panel_set_value(repeat_pi, str);
  996. X        }
  997. X        panel_set(whichwk_pi, PANEL_SHOW_ITEM, FALSE, 0);
  998. X        panel_set(repeat_pi, PANEL_SHOW_ITEM, TRUE, 0);
  999. X    }
  1000. X    panel_set_value(everyx_pi, everyx_val);
  1001. X    panel_set_value(whichwk_pi, whichwk_val);
  1002. X    if (apt->flags & LOOKAHEAD) {
  1003. X        sprintf(str, "%d", apt->lookahead);
  1004. X        panel_set_value(remind_pi, str);
  1005. X    }
  1006. X    if (apt->flags & RUN) {
  1007. X        sprintf(str, "%d", apt->runlength);
  1008. X        panel_set_value(runl_pi, str);
  1009. X    }
  1010. X    panel_set_value(marked_pi, (apt->flags & MARKED ? 1 : 0));
  1011. X    sprintf(str, "%d", apt->warn);
  1012. X    panel_set_value(advw_pi, str);
  1013. X    if (apt->flags & A_NOTE)
  1014. X        panel_set(marked_pi, PANEL_SHOW_ITEM, TRUE, 0);
  1015. X    else
  1016. X        panel_set(marked_pi, PANEL_SHOW_ITEM, FALSE, 0);
  1017. X}
  1018. X
  1019. X/* "more" button selected. Display next appt in rotation. */
  1020. Xnext_appt(bi, dpyflag)
  1021. Xint bi;
  1022. Xint dpyflag;
  1023. X{
  1024. X    static int loopcnt = 0;
  1025. X
  1026. X    if (slots[bi].active)
  1027. X        deactivate_slot(bi, dpyflag);
  1028. X
  1029. X    if (slots[bi].cur_appt->next == NULL) {
  1030. X        /* end of the chain */
  1031. X        slots[bi].cur_appt = slots[bi].first;
  1032. X        if (loopcnt) {
  1033. X            /* infinite loop detected */
  1034. X            loopcnt = 0;
  1035. X            return;
  1036. X        } else
  1037. X            ++loopcnt;
  1038. X    } else
  1039. X        /* activate next in chain */
  1040. X        slots[bi].cur_appt = slots[bi].cur_appt->next;
  1041. X    /* make sure it is not a deleted one */
  1042. X    if (chk_deleted(&slots[bi], slots[bi].cur_appt))
  1043. X        next_appt(bi, dpyflag); /* try next in chain */
  1044. X    else if (!activate_slot(bi, dpyflag))
  1045. X        next_appt(bi, dpyflag); /* try next in chain */
  1046. X    loopcnt = 0;
  1047. X}
  1048. X
  1049. X/* left scroll arrow selected */
  1050. Xdo_left_arrow(canvas, bi)
  1051. XCanvas canvas;
  1052. Xint bi;
  1053. X{
  1054. X    struct timeval timeout;
  1055. X    Event event;
  1056. X    int fd, ertn, flags;
  1057. X
  1058. X    if (!slots[bi].active || strlen(slots[bi].cur_appt->str) < day_message_size)
  1059. X        return;
  1060. X    timeout.tv_sec = 0L;
  1061. X    timeout.tv_usec = 100000L;    /* 1/10 sec */
  1062. X    fd = (int)window_get(canvas, WIN_FD);
  1063. X    flags = fcntl(fd, F_GETFL, 0);
  1064. X    (void)fcntl(fd, F_SETFL, flags|FNDELAY);
  1065. X    /* reverse video the arrow */
  1066. X    pw_rop(main_pixwin, slots[bi].larrow_pos.left, slots[bi].larrow_pos.top,
  1067. X        19, 14, PIX_NOT(PIX_DST), leftarrow, 0, 0);
  1068. X    while (TRUE) {
  1069. X        if (slots[bi].cur_appt->sindex < strlen(slots[bi].cur_appt->str)) {
  1070. X            ++slots[bi].cur_appt->sindex;
  1071. X            rewrite_string(bi, JUSTIFY_INDEX);
  1072. X            /* reverse video the arrow (rewrite changed it) */
  1073. X            pw_rop(main_pixwin, slots[bi].larrow_pos.left, slots[bi].larrow_pos.top,
  1074. X                19, 14, PIX_NOT(PIX_DST), leftarrow, 0, 0);
  1075. X        }
  1076. X        /* do this garbage to handle a repeat function */
  1077. X        (void)select(0, NULL, NULL, NULL, &timeout);
  1078. X        ertn = window_read_event(canvas, &event);
  1079. X        if (ertn != -1 && event_is_up(&event))
  1080. X            break;
  1081. X    }
  1082. X    /* put arrow back to normal */
  1083. X    pw_rop(main_pixwin, slots[bi].larrow_pos.left, slots[bi].larrow_pos.top,
  1084. X        19, 14, PIX_SRC, leftarrow, 0, 0);
  1085. X    (void)fcntl(fd, F_SETFL, flags & ~FNDELAY);
  1086. X}
  1087. X
  1088. X/* right scroll arrow selected */
  1089. Xdo_right_arrow(canvas, bi)
  1090. XCanvas canvas;
  1091. Xint bi;
  1092. X{
  1093. X    struct timeval timeout;
  1094. X    Event event;
  1095. X    int fd, ertn, flags;
  1096. X
  1097. X    if (!slots[bi].active || strlen(slots[bi].cur_appt->str) < day_message_size)
  1098. X        return;
  1099. X    timeout.tv_sec = 0L;
  1100. X    timeout.tv_usec = 100000L;    /* 1/10 sec */
  1101. X    fd = (int)window_get(canvas, WIN_FD);
  1102. X    flags = fcntl(fd, F_GETFL, 0);
  1103. X    (void)fcntl(fd, F_SETFL, flags|FNDELAY);
  1104. X    /* reverse video the arrow */
  1105. X    pw_rop(main_pixwin, slots[bi].rarrow_pos.left, slots[bi].rarrow_pos.top,
  1106. X        19, 14, PIX_NOT(PIX_DST), rightarrow, 0, 0);
  1107. X    while (TRUE) {
  1108. X        if (slots[bi].cur_appt->sindex > 0) {
  1109. X            --slots[bi].cur_appt->sindex;
  1110. X            rewrite_string(bi, JUSTIFY_INDEX);
  1111. X            /* reverse video the arrow (rewrite changed it) */
  1112. X            pw_rop(main_pixwin, slots[bi].rarrow_pos.left, slots[bi].rarrow_pos.top,
  1113. X                19, 14, PIX_NOT(PIX_DST), rightarrow, 0, 0);
  1114. X        }
  1115. X        /* do this garbage to handle a repeat function */
  1116. X        (void)select(0, NULL, NULL, NULL, &timeout);
  1117. X        ertn = window_read_event(canvas, &event);
  1118. X        if (ertn != -1 && event_is_up(&event))
  1119. X            break;
  1120. X    }
  1121. X    pw_rop(main_pixwin, slots[bi].rarrow_pos.left, slots[bi].rarrow_pos.top,
  1122. X        19, 14, PIX_SRC, rightarrow, 0, 0);
  1123. X    (void)fcntl(fd, F_SETFL, flags & ~FNDELAY);
  1124. X}
  1125. X
  1126. X/*
  1127. X * get_shelf - get text from selection service shelf for copy
  1128. X * operation. From Mark Feblowitz <mdf0%shemesh@gte.COM>.
  1129. X */
  1130. Xstatic
  1131. Xchar *
  1132. Xget_shelf()
  1133. X{
  1134. X    Seln_holder    holder;
  1135. X    Seln_request    *buffer;
  1136. X
  1137. X    holder = seln_inquire(SELN_SHELF);
  1138. X    /* do we have the shelf? */
  1139. X    if (!seln_holder_same_process(&holder)) {
  1140. X        buffer = seln_ask(&holder, SELN_REQ_CONTENTS_ASCII, 0, 0);
  1141. X        (void) strncpy(sel_text, buffer->data + sizeof(Seln_attribute),
  1142. X            MAX_STRLEN-1);
  1143. X        sel_text[MAX_STRLEN-1] = '\0';
  1144. X        if (strlen(sel_text) == 0)
  1145. X            /* empty string is no sel. */
  1146. X            return(NULL);
  1147. X        sel_text[MAX_STRLEN-1] = '\0';
  1148. X    }
  1149. X    return(sel_text);
  1150. X}
  1151. X
  1152. X/*
  1153. X * respond to function keys the selection service thinks
  1154. X * are important
  1155. X */
  1156. Xvoid
  1157. Xsel_func_key_proc(client_data, args)
  1158. Xchar *client_data;
  1159. XSeln_function_buffer *args;
  1160. X{
  1161. X    Seln_holder *holder;
  1162. X    Seln_response resp;
  1163. X
  1164. X    if ((resp = seln_figure_response(args, &holder)) == SELN_SHELVE) {
  1165. X        /* put string for current appt on the shelf */
  1166. X        if (found_flag == FOUND_SLOT && slots[box_index].active)
  1167. X            /* we're in an active slot */
  1168. X            strcpy(sel_text, slots[box_index].cur_appt->str);
  1169. X        else
  1170. X            sel_text[0] = '\0';
  1171. X    }
  1172. X}
  1173. X
  1174. X/*
  1175. X * called by selection svc library when someone requests our shelf
  1176. X * text. Abridged from the seln_demo() in the SunView manual.
  1177. X */
  1178. XSeln_result
  1179. Xsel_reply_proc(item, context, length)
  1180. XSeln_attribute item;
  1181. XSeln_replier_data *context;
  1182. Xint length;
  1183. X{
  1184. X    char *destp, *seln = NULL;
  1185. X    int size;
  1186. X
  1187. X    if (context->rank == SELN_SHELF)
  1188. X        seln = sel_text;
  1189. X    
  1190. X    switch (item) {
  1191. X        case SELN_REQ_CONTENTS_ASCII:
  1192. X            /* send the contents of the selection buffer */
  1193. X            if (seln == NULL)
  1194. X                return(SELN_DIDNT_HAVE);
  1195. X            context->context = seln;
  1196. X            size = strlen(seln);
  1197. X            destp = (char *)context->response_pointer;
  1198. X            /* allow for padding */
  1199. X            (void) strncpy(destp, seln, length-8);
  1200. X            destp += size;
  1201. X            /* pad to long word */
  1202. X            while ((int)destp % 4 != 0)
  1203. X                *destp++ = '\0';
  1204. X            context->response_pointer = (char **)destp;
  1205. X            *context->response_pointer++ = 0;
  1206. X            break;
  1207. X        
  1208. X        case SELN_REQ_YIELD:
  1209. X            *context->response_pointer++ = (char *)SELN_SUCCESS;
  1210. X            break;
  1211. X        
  1212. X        case SELN_REQ_BYTESIZE:
  1213. X            if (seln == NULL)
  1214. X                return(SELN_DIDNT_HAVE);
  1215. X            *context->response_pointer++ = (char *)strlen(seln);
  1216. X            break;
  1217. X            
  1218. X        case SELN_REQ_END_REQUEST:
  1219. X            break;
  1220. X        
  1221. X        default:
  1222. X            return(SELN_UNRECOGNIZED);
  1223. X    }
  1224. X
  1225. X    return(SELN_SUCCESS);
  1226. X}
  1227. END_OF_FILE
  1228. if test 30220 -ne `wc -c <'devent.c'`; then
  1229.     echo shar: \"'devent.c'\" unpacked with wrong size!
  1230. fi
  1231. # end of 'devent.c'
  1232. fi
  1233. if test -f 'event.h' -a "${1}" != "-c" ; then 
  1234.   echo shar: Will not clobber existing file \"'event.h'\"
  1235. else
  1236. echo shar: Extracting \"'event.h'\" \(1467 characters\)
  1237. sed "s/^X//" >'event.h' <<'END_OF_FILE'
  1238. X/*
  1239. X * $Header: event.h,v 2.2 91/02/01 12:19:43 billr Exp $
  1240. X */
  1241. X/*
  1242. X * event.h
  1243. X *
  1244. X * Author: Philip Heller, Sun Microsystems. Inc. <terrapin!heller@sun.com>
  1245. X *
  1246. X * Original source Copyright (C) 1987, Sun Microsystems, Inc.
  1247. X *    All Rights Reserved
  1248. X * Permission is hereby granted to use and modify this program in source
  1249. X * or binary form as long as it is not sold for profit and this copyright
  1250. X * notice remains intact.
  1251. X *
  1252. X *
  1253. X * Changes/additions by: Bill Randle, Tektronix, Inc. <billr@saab.CNA.TEK.COM>
  1254. X *
  1255. X * Changes and additions Copyright (C) 1988, 1989, 1991 Tektronix, Inc.
  1256. X *    All Rights Reserved
  1257. X * Permission is hereby granted to use and modify the modifications in source
  1258. X * or binary form as long as they are not sold for profit and this copyright
  1259. X * notice remains intact.
  1260. X */
  1261. X
  1262. Xextern struct dayslot *slots;
  1263. Xextern int mainsw_state, day_is_open;
  1264. Xextern struct rect_limits boxlims[];
  1265. Xextern struct rect_limits mboxlims[];
  1266. Xextern int selected_type, read_only, new_entry;
  1267. Xextern int dayslot_width, nr_weekdays, day_message_size;
  1268. Xextern int dayslot_height, weekslot_height, weekslot_width;
  1269. Xextern int ybox_height, ybox_width;
  1270. Xextern struct weekrect week_boxes[];
  1271. Xextern Pixwin *main_pixwin;
  1272. Xextern Pixfont *font;
  1273. Xextern Cursor month_cursor, week_cursor, day_cursor;
  1274. Xextern Pixrect *smallarrow_pr, *arrowhead_pr, *arrowshaft_pr;
  1275. Xextern struct week_arrow week_arrows[];
  1276. Xextern struct tm current;
  1277. Xextern struct tm today;
  1278. Xextern Pixrect *timeslot_td_pr, *morebutton;
  1279. X
  1280. END_OF_FILE
  1281. if test 1467 -ne `wc -c <'event.h'`; then
  1282.     echo shar: \"'event.h'\" unpacked with wrong size!
  1283. fi
  1284. # end of 'event.h'
  1285. fi
  1286. if test -f 'mpaint.c' -a "${1}" != "-c" ; then 
  1287.   echo shar: Will not clobber existing file \"'mpaint.c'\"
  1288. else
  1289. echo shar: Extracting \"'mpaint.c'\" \(9590 characters\)
  1290. sed "s/^X//" >'mpaint.c' <<'END_OF_FILE'
  1291. X/*
  1292. X * $Header: mpaint.c,v 2.5 91/03/27 16:45:56 billr Exp $
  1293. X */
  1294. X/*
  1295. X * mpaint.c
  1296. X *
  1297. X * Author: Philip Heller, Sun Microsystems. Inc. <terrapin!heller@sun.com>
  1298. X *
  1299. X * Original source Copyright (C) 1987, Sun Microsystems, Inc.
  1300. X *    All Rights Reserved
  1301. X * Permission is hereby granted to use and modify this program in source
  1302. X * or binary form as long as it is not sold for profit and this copyright
  1303. X * notice remains intact.
  1304. X *
  1305. X *
  1306. X * Changes/additions by: Bill Randle, Tektronix, Inc. <billr@saab.CNA.TEK.COM>
  1307. X *
  1308. X * Changes and additions Copyright (C) 1988, 1989, 1991 Tektronix, Inc.
  1309. X *    All Rights Reserved
  1310. X * Permission is hereby granted to use and modify the modifications in source
  1311. X * or binary form as long as they are not sold for profit and this copyright
  1312. X * notice remains intact.
  1313. X */
  1314. X/***************************************************
  1315. X *                           *
  1316. X *    Artistic routines that draw in the main    *
  1317. X * subwindow for the month display.           *
  1318. X *                           *
  1319. X ***************************************************/
  1320. X
  1321. X#include <suntool/sunview.h>
  1322. X#include <suntool/canvas.h>
  1323. X#include <ctype.h>
  1324. X#include <stdio.h>
  1325. X#include "ct.h"
  1326. X#include "paint.h"
  1327. X#ifndef NO_HOLIDAYS
  1328. Xextern struct appt_entry a_appts[], c_appts[];
  1329. Xextern struct appt_entry i_appts[], j_appts[];
  1330. Xextern struct appt_entry s_appts[];
  1331. X#endif
  1332. X
  1333. X/*
  1334. X * Routine to draw month calendar.
  1335. X */
  1336. X
  1337. Xdraw_month()
  1338. X{
  1339. X    int start_dow, i, j, k, x, y, n_days;
  1340. X    int days_in_week;
  1341. X    int arrow_index, last_top, index;
  1342. X    char c[4], title[20], *cp;
  1343. X    int left_border, right_border, top_border, bottom_border;
  1344. X    Rect *rect;
  1345. X    int busy_today[31];
  1346. X    FILE *apts;
  1347. X    int read_stat;
  1348. X    struct tm Save;
  1349. X    struct appt_entry appt;
  1350. X    int runl;
  1351. X
  1352. X    lock_cursors();
  1353. X    /* destory future appts popup, if it exists */
  1354. X    if (fframe) {
  1355. X        window_destroy(fframe);
  1356. X        fframe = 0;
  1357. X    }
  1358. X    fix_current_day();
  1359. X    Save = current;
  1360. X    current.tm_mday = 1;
  1361. X    fix_current_day();
  1362. X    working(TRUE);
  1363. X    start_dow = current.tm_wday;
  1364. X    n_days = monthlength(current.tm_mon);
  1365. X    
  1366. X    pw_batch_on(main_pixwin);
  1367. X        rect = (Rect *) window_get(canvas, WIN_RECT);
  1368. X    /* Erase the window */
  1369. X        pw_writebackground(main_pixwin,0,0,rect->r_width,rect->r_height,PIX_CLR);
  1370. X        left_border = (rect->r_width - 7*64)/2 + 32;
  1371. X        top_border = (rect->r_height - 5*64) / 2;
  1372. X        right_border = left_border + 7*64;
  1373. X         
  1374. X    sprintf(title, "%s, %d",
  1375. X        monthnames[current.tm_mon], 1900 + current.tm_year);
  1376. X        pw_text(main_pixwin, (rect->r_width - bigfont->pf_defaultsize.x*strlen(title))/2 + 32, top_border/2 +  7,
  1377. X          PIX_SRC, bigfont, title);
  1378. X    sun_moon_buttons(FALSE);
  1379. X    print_button(TRUE);
  1380. X
  1381. X    for (i=0; i<31; i++)        /* Which days have appointments? */
  1382. X        busy_today[i] = 0;
  1383. X    if ((apts = fopen(apts_pathname, "r")) == NULL)
  1384. X        err_rpt("can't open appointments file", FATAL);
  1385. X    First = current;
  1386. X    current.tm_mday = monthlength(current.tm_mon);
  1387. X    fix_current_day();
  1388. X    Last = current;
  1389. X    working(FALSE);
  1390. X    while ((read_stat = get_aentry(apts, &appt, FALSE, 1, First.tm_mon+1)) != EOF) {
  1391. X        if (read_stat)
  1392. X            continue;    /* read error (ignore) */
  1393. X        if (appt.flags & A_COMMENT)
  1394. X            continue;
  1395. X        if ((appt.flags & MARKED_NOTE) == MARKED_NOTE)
  1396. X            continue;
  1397. X        current.tm_year = appt.year;
  1398. X        current.tm_mon = appt.month;
  1399. X        current.tm_mday = appt.day;
  1400. X        if (appt.flags & ALL_YEARS)
  1401. X            current.tm_year = First.tm_year;
  1402. X        if (appt.flags & ALL_MONTHS)
  1403. X            current.tm_mon = First.tm_mon;
  1404. X        if (appt.flags & EVERY_SOMEDAY) {
  1405. X            if ((current.tm_mon == First.tm_mon) && (current.tm_year == First.tm_year)) {
  1406. X                /* find first occurance of this day this month */
  1407. X                current.tm_mday = First.tm_mday;
  1408. X                find_date(&appt);
  1409. X                if (appt.flags & RUN)
  1410. X                    runl = appt.runlength;
  1411. X                else
  1412. X                    runl = 1;
  1413. X            } else if (appt.flags & RUN) {
  1414. X                runl = appt.runlength;
  1415. X                find_date(&appt);
  1416. X                while (ymd_compare(current, First) < 0 && --runl) {
  1417. X                    current.tm_mday += 7;
  1418. X                    find_date(&appt);
  1419. X                }
  1420. X                if (ymd_compare(current, First) < 0) {
  1421. X                    /* ran out of runlength */
  1422. X                    continue;
  1423. X                }
  1424. X            } else
  1425. X                continue;
  1426. X            while (ymd_compare(current, Last) <= 0 && runl) {
  1427. X                if (chk_week(appt.repeat, current.tm_mday)) {
  1428. X                    if (runl)
  1429. X                        busy_today[current.tm_mday-1]++;
  1430. X                    if (appt.flags & RUN)
  1431. X                        --runl;
  1432. X                }
  1433. X                current.tm_mday += 7;
  1434. X                fix_current_day();
  1435. X            }
  1436. X        } else if ((appt.flags & REPEAT) && !(appt.flags & ALL_DAYS)
  1437. X            && !(appt.flags & EVERY_MON_FRI)) {
  1438. X            if (appt.flags & EVERY_SOMEDAY)
  1439. X                continue;
  1440. X            if (appt.flags & RUN)
  1441. X                runl = appt.runlength;
  1442. X            else
  1443. X                runl = 1;
  1444. X            while (ymd_compare(current, First) < 0 && runl) {
  1445. X                if (appt.flags & RUN)
  1446. X                    --runl;
  1447. X                if (runl) {
  1448. X                    current.tm_mday += appt.repeat;
  1449. X                    fix_current_day();
  1450. X                }
  1451. X            }
  1452. X            while (ymd_compare(current, Last) <= 0 && runl) {
  1453. X                if (runl) {
  1454. X                    busy_today[current.tm_mday-1]++;
  1455. X                    current.tm_mday += appt.repeat;
  1456. X                    fix_current_day();
  1457. X                    if (appt.flags & RUN)
  1458. X                        --runl;
  1459. X                }
  1460. X            }
  1461. X        } else if (current.tm_year == First.tm_year 
  1462. X            && current.tm_mon == First.tm_mon) {
  1463. X            if (appt.flags & ALL_DAYS)
  1464. X                for (i=0; i<monthlength(First.tm_mon); i++)
  1465. X                    busy_today[i]++;
  1466. X            else if (appt.flags & EVERY_MON_FRI)
  1467. X                for (i=0,j=First.tm_wday; i<monthlength(First.tm_mon); i++,j++) {
  1468. X                    if (j > SAT)
  1469. X                        j = SUN;
  1470. X                    else if (j >= MON && j <= FRI)
  1471. X                        busy_today[i]++;
  1472. X                }
  1473. X            else if (appt.flags & DELETED)
  1474. X                busy_today[appt.day-1]--;
  1475. X            else
  1476. X                busy_today[appt.day-1]++;
  1477. X        }
  1478. X                
  1479. X    }
  1480. X    fclose(apts);
  1481. X    current = First;
  1482. X    fix_current_day();
  1483. X#ifndef NO_HOLIDAYS
  1484. X    /*
  1485. X     * now that we've gone thru the appointments file,
  1486. X     * check to see if the user has selected any holiday
  1487. X     * options and add them in.
  1488. X     */
  1489. X    for (i=0; i<monthlength(First.tm_mon); i++) {
  1490. X        working(TRUE);
  1491. X        if (holiday_a == 1) {
  1492. X            j = a_dates(holiday_a);
  1493. X            for (k=0; k<j; k++)
  1494. X                if (ymd2_compare(¤t, &a_appts[k]) == 0)
  1495. X                    busy_today[i]++;
  1496. X        }
  1497. X        if (holiday_c == 1) {
  1498. X            j = c_dates(holiday_c);
  1499. X            for (k=0; k<j; k++)
  1500. X                if (ymd2_compare(¤t, &c_appts[k]) == 0)
  1501. X                    busy_today[i]++;
  1502. X        }
  1503. X        working(FALSE);
  1504. X        if (holiday_i == 1) {
  1505. X            j = i_dates(holiday_i);
  1506. X            for (k=0; k<j; k++)
  1507. X                if (ymd2_compare(¤t, &i_appts[k]) == 0)
  1508. X                    busy_today[i]++;
  1509. X        }
  1510. X        working(TRUE);
  1511. X        if (holiday_j == 1) {
  1512. X            j = j_dates(holiday_j);
  1513. X            for (k=0; k<j; k++)
  1514. X                if (ymd2_compare(¤t, &j_appts[k]) == 0)
  1515. X                    busy_today[i]++;
  1516. X        }
  1517. X        if (holiday_s == 1) {
  1518. X            j = s_dates(holiday_s);
  1519. X            for (k=0; k<j; k++)
  1520. X                if (ymd2_compare(¤t, &s_appts[k]) == 0)
  1521. X                    busy_today[i]++;
  1522. X        }
  1523. X        current.tm_mday++;
  1524. X        working(FALSE);
  1525. X    }
  1526. X    current = First;
  1527. X    fix_current_day();
  1528. X#endif
  1529. X
  1530. X    y = top_border;                /* Draw all day boxes. */
  1531. X    if (monday_first) {
  1532. X        if (start_dow == SUN) {
  1533. X            x = 64*6 + left_border;
  1534. X            days_in_week = 6;
  1535. X        } else {
  1536. X            x = 64*(start_dow - 1) + left_border;
  1537. X            days_in_week = start_dow -1 ;
  1538. X        }
  1539. X    } else {
  1540. X        x = 64*start_dow + left_border;
  1541. X        days_in_week = start_dow;
  1542. X    }
  1543. X        c[0] = ' ';
  1544. X        c[1] = '1';
  1545. X        c[2] = ' ';
  1546. X        c[3] = '\0';
  1547. X        for (i=0; i<n_days; i++){
  1548. X        if (ymd_compare(today, current) == 0)
  1549. X            /* gray box */
  1550. X            pw_write(main_pixwin,x,y,64,64,PIX_SRC,daybox_td_pr,0,0);
  1551. X        else
  1552. X            pw_write(main_pixwin,x,y,64,64,PIX_SRC,daybox_pr,0,0);
  1553. X        if (busy_today[i] > 0)
  1554. X            pw_write(main_pixwin, x+46, y+2, 16, 16,
  1555. X              PIX_SRC|PIX_DST, triangle_pr, 0, 0);
  1556. X                boxlims[i].lowx = x;
  1557. X                boxlims[i].lowy = y;
  1558. X                boxlims[i].highx = x + 63;
  1559. X                boxlims[i].highy = y + 63;
  1560. X        pw_text(main_pixwin,x+6,y+21,PIX_SRC|PIX_DST,bigfont,c);
  1561. X                days_in_week++;
  1562. X        current.tm_mday++;
  1563. X                if (days_in_week == 7){
  1564. X                        days_in_week = 0;
  1565. X                        x = left_border;
  1566. X                        y += 64;
  1567. X                }
  1568. X        else
  1569. X                        x += 64;
  1570. X                if (c[1] != '9')
  1571. X                        c[1]++;
  1572. X                else {
  1573. X                        c[1] = '0';
  1574. X                        if (c[0] == ' ')
  1575. X                                c[0] = '1';
  1576. X                        else
  1577. X                                c[0]++;
  1578. X                }
  1579. X        }
  1580. X        x = left_border + 27;
  1581. X        y = top_border - 16;
  1582. X    if (monday_first) {
  1583. X        for (i=1; i<7; i++) {        /* Mon ... Sat Sun */
  1584. X            pw_char(main_pixwin,x,y,PIX_SRC,bigfont,daynames[i][0]);
  1585. X            x += 64;
  1586. X        }
  1587. X        pw_char(main_pixwin,x,y,PIX_SRC,bigfont,daynames[0][0]);
  1588. X    } else {
  1589. X        for (i=0; i<7; i++) {        /* Sun Mon ... Sat */
  1590. X            pw_char(main_pixwin,x,y,PIX_SRC,bigfont,daynames[i][0]);
  1591. X            x += 64;
  1592. X        }
  1593. X        }
  1594. X
  1595. X    bottom_border = boxlims[n_days-1].highy;
  1596. X
  1597. X        /* Draw the "week arrows" */
  1598. X        arrow_index = 0;
  1599. X        last_top = -1;
  1600. X
  1601. X    current = First;
  1602. X        for (i=0; i<n_days; i++)
  1603. X                if (boxlims[i].lowy > last_top) {
  1604. X                        last_top = boxlims[i].lowy;
  1605. X                        week_arrows[arrow_index].active = 1;
  1606. X                        week_arrows[arrow_index].left = left_border - 64;
  1607. X                        week_arrows[arrow_index].top = last_top + 12;
  1608. X                        week_arrows[arrow_index].right =
  1609. X                          week_arrows[arrow_index].left + 43;
  1610. X                        week_arrows[arrow_index].bottom =
  1611. X                          week_arrows[arrow_index].top + 28;
  1612. X                        pw_write(main_pixwin, left_border-64, last_top + 12,
  1613. X                          43, 29, PIX_SRC, weekarrow_pr, 0, 0);
  1614. X
  1615. X            /*  Week numbers  */
  1616. X            sprintf(c, "%2d", week_number());
  1617. X            pw_text(main_pixwin, left_border-54, last_top+32, 
  1618. X                PIX_SRC, font, c);
  1619. X            current.tm_mday += 7;
  1620. X            fix_current_day();
  1621. X
  1622. X                        arrow_index++;
  1623. X                }
  1624. X    pw_batch_off(main_pixwin);
  1625. X    current = Save;
  1626. X    unlock_cursors();
  1627. X}
  1628. END_OF_FILE
  1629. if test 9590 -ne `wc -c <'mpaint.c'`; then
  1630.     echo shar: \"'mpaint.c'\" unpacked with wrong size!
  1631. fi
  1632. # end of 'mpaint.c'
  1633. fi
  1634. echo shar: End of archive 15 \(of 23\).
  1635. cp /dev/null ark15isdone
  1636. MISSING=""
  1637. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ; do
  1638.     if test ! -f ark${I}isdone ; then
  1639.     MISSING="${MISSING} ${I}"
  1640.     fi
  1641. done
  1642. if test "${MISSING}" = "" ; then
  1643.     echo You have unpacked all 23 archives.
  1644.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1645. else
  1646.     echo You still need to unpack the following archives:
  1647.     echo "        " ${MISSING}
  1648. fi
  1649. ##  End of shell archive.
  1650. exit 0
  1651.  
  1652. exit 0 # Just in case...
  1653. -- 
  1654. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1655. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1656. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1657. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1658.